package com.unbox.admin.service.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.unbox.admin.entity.Enumeration;
import com.unbox.admin.entity.File;
import com.unbox.admin.entity.Setting;
import com.unbox.admin.service.IEnumerationService;
import com.unbox.admin.service.IFileService;
import com.unbox.admin.service.ISettingService;
import com.unbox.admin.service.IUploadFileService;
import com.unbox.admin.util.JavaCvUtil;
import com.unbox.common.enums.UploadFileEnum;
import com.unbox.common.util.FileUitl;
import com.unbox.common.util.UnBoxUtils;
import com.unbox.common.util.UnboxLog;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

@Service
public class UploadFileServiceImpl implements IUploadFileService {

    /**
     * 国际化日志输出
     */
    UnboxLog unboxLog = new UnBoxUtils.LocaleMessageLog(UploadFileServiceImpl.class);

    @Autowired
    IFileService fileService;

    @Autowired
    ISettingService iSettingService;

    @Autowired
    IEnumerationService enumerationService;

    @Override
    public File uploadFile(MultipartFile multipartFile) {
        File file = null;
        Setting setting = iSettingService.getById(1);
        if (setting.getOssType().equals(UploadFileEnum.ALI.getValue())) {
            file = aliOss(setting, multipartFile);
        } else if (setting.getOssType().equals(UploadFileEnum.FILE.getValue())) {
            file = localUpload(setting, multipartFile);
        }
        return file;
    }

    /**
     * 获取文件类型
     * @param fileType
     * @param file
     * @return
     */
    private void getFileType(Setting setting,String fileType, File file, byte[] fileDatas) {
        Enumeration enumeration = new Enumeration();
        enumeration.setName("file_type_eq");
        enumeration.setKeys(fileType);
        enumeration = enumerationService.get(enumeration);
        if (ObjectUtils.isEmpty(enumeration)) {
            file.setType("other");
        } else {
            file.setType(enumeration.getValues());

            // 类型是视频截图视频图片上传到文件库中
            if (file.getType().equals(UploadFileEnum.VIDEO.getValue())) {
                uploadVideoPic(setting, fileDatas, file);
            }
        }
    }

    /**
     * 上传获取视频的截图
     * @param fileDatas
     * @param file
     */
    private void uploadVideoPic(Setting setting ,byte[] fileDatas, File file) {
        byte[] files = JavaCvUtil.videoToPic(fileDatas);
        String folderUrl = FileUitl.getNameDateRandomFolder("jpg");
        String fileUrl = FileUitl.getFileNameDateRandomFolderFile("jpg");
        try(InputStream stream = new ByteArrayInputStream(files)) {
            file.setAbbreviationImg(folderUrl+fileUrl);
            if (setting.getOssType().equals(UploadFileEnum.ALI.getValue())) {
                aliOss(setting, file, files);
            } else if (setting.getOssType().equals(UploadFileEnum.FILE.getValue())) {
                FileUitl.savePic(stream,setting.getLocalFile()+folderUrl,fileUrl);
            }
            unboxLog.info("oss.opencv.video.to.image.message", file.getName());
        } catch (IOException e) {
           unboxLog.error("oss.opencv.video.to.image.error", e.getMessage());
        }
    }

    /**
     * 本地上传文件
     * @param setting
     * @param multipartFile
     * @return
     */
    private File localUpload(Setting setting, MultipartFile multipartFile) {
        File file = new File();
        String suffix = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf(".") + 1);
        String folderUrl = FileUitl.getNameDateRandomFolder(suffix);
        String fileUrl = FileUitl.getFileNameDateRandomFolderFile(suffix);
        file.setUrl(folderUrl+fileUrl);
        file.setName(multipartFile.getOriginalFilename());
        file.setSaveSource("file");
        file.setSuffix(suffix);
        file.setSource("upload");
        file.setDnsUrl(setting.getLocalDns());
        try (InputStream stream = new ByteArrayInputStream(multipartFile.getBytes())) {
            String fileType = FileUitl.getMimeType(multipartFile.getBytes(), multipartFile.getOriginalFilename());
            getFileType(setting, fileType, file, multipartFile.getBytes());
            FileUitl.savePic(stream,setting.getLocalFile()+folderUrl,fileUrl);
            unboxLog.info("oss.upload.message", file.getName(), fileType);
        } catch (IOException e) {
            unboxLog.error("oss.upload.error", e.getMessage());
        }
        return file;
    }

    /**
     * 上传到阿里oss
     * @param multipartFile
     * @return
     */
    private File aliOss(Setting setting,MultipartFile multipartFile) {
        File file = new File();
        String suffix = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf(".") + 1);
        String url = FileUitl.getFileNameDateRandom(suffix);
        String endpoint = setting.getAliEndpoint();
        String accessKeyId = setting.getAliAccessKeyId();
        String accessKeySecret = setting.getAliAccessKeySecret();
        String bucketName = setting.getAliBucketName();
        String objectName = multipartFile.getOriginalFilename();
        file.setSuffix(suffix);
        file.setUrl(url);
        file.setName(multipartFile.getOriginalFilename());
        file.setSaveSource("ali");
        file.setSource("upload");
        file.setDnsUrl(setting.getAliOssDns());
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try (InputStream stream = new ByteArrayInputStream(multipartFile.getBytes())){
            String fileType = FileUitl.getMimeType(multipartFile.getBytes(), multipartFile.getOriginalFilename());
            getFileType(setting, fileType, file, multipartFile.getBytes());
            ossClient.putObject(bucketName, url,stream);
            unboxLog.info("oss.upload.message", objectName, fileType);
        } catch (IOException e) {
            unboxLog.error("oss.upload.error", e.getMessage());
        }
        ossClient.shutdown();
        return file;
    }

    /**
     * 上传到阿里oss
     * @param fileDatas
     * @return
     */
    private void aliOss(Setting setting, File file, byte[] fileDatas) {
        String endpoint = setting.getAliEndpoint();
        String accessKeyId = setting.getAliAccessKeyId();
        String accessKeySecret = setting.getAliAccessKeySecret();
        String bucketName = setting.getAliBucketName();
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try (InputStream stream = new ByteArrayInputStream(fileDatas)){
            ossClient.putObject(bucketName, file.getAbbreviationImg(), stream);
            unboxLog.info("oss.upload.message", file.getAbbreviationImg());
        } catch (IOException e) {
            unboxLog.error("oss.upload.error", e.getMessage());
        }
        ossClient.shutdown();
    }
}
